import type { MineListType } from '@/types/mine'
import { aroundMark, createMine } from '@/utils/mine'
import { defineStore } from 'pinia'

export default defineStore('mine', {
    state: () => ({
        level: 0,
        levelList: [
            { id: 0, name: '初级', width: 10, height: 10, mine: 10 },
            { id: 1, name: '中级', width: 15, height: 15, mine: 50 },
            { id: 2, name: '高级', width: 35, height: 25, mine: 160 },
        ],
        over: false,
        play: false,
        active: [] as number[],
        mineList: undefined as MineListType[][] | undefined,
        boom: undefined as [number, number] | undefined
    }),
    getters: {
        getLevel: (state) => {
            return state.levelList.filter(item => item.id === state.level)[0]
        },
        mark: (state) => {
            return state.mineList?.reduce((n, i) => i.filter(j => j.mark == 1).length + n, 0) || 0
        },
        unknown: (state) => {
            return state.mineList?.reduce((n, i) => i.filter(j => !j.open).length + n, 0) || 0
        },
    },
    actions: {
        markMine(row: number, col: number) {
            if (this.mineList?.[row]?.[col].open) return
            this.mineList![row][col].mark = (this.mineList![row][col].mark + 1) % 3 as 0 | 1 | 2
            if (this.getLevel.mine == this.unknown) {
                this.setOver()
            }
        },
        reset() {
            this.over = false
            this.play = false
            this.boom = undefined
            this.createMineList()
            console.log('reset')
        },
        setLevel(level: number) {
            if (level == this.level) return
            this.level = level
            this.reset()
        },
        createMineList() {
            this.mineList = new Array(this.getLevel.height).fill(0)
                .map(_ => new Array(this.getLevel.width).fill(0)
                    .map(_ => ({
                        value: 0,
                        mark: 0,
                        open: false,
                        around: 0
                    }))) as unknown as MineListType[][]
            createMine(this.mineList, this.getLevel.mine)
        },
        openMine(row: number, col: number) {
            if (this.mineList![row][col].open) return
            if (this.mineList![row][col].value) {
                this.setOver()
                return 'boom'
            }
            if (this.mineList![row][col].value === 0 || aroundMark(this.mineList!, row, col) == this.mineList![row][col].around) {
                this.mineList![row][col].open = true
                if (this.mineList![row][col].around === 0) {
                    for (let x = -1; x <= 1; x++) {
                        for (let y = -1; y <= 1; y++) {
                            if (x || y) {
                                const ix = row + x, iy = col + y
                                if (ix >= 0 && ix < this.getLevel.height && iy >= 0 && iy < this.getLevel.width) {
                                    this.openMine(ix, iy)
                                }
                            }
                        }
                    }
                }
            }
            if (this.unknown == this.getLevel.mine) {
                this.setOver()
            }
        },
        setOver() {
            console.log('end')
            this.play = false
            this.over = true
        },
    }
})